From 254692941de24e2c73f61d337c738c1445bf4dc2 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 3 Sep 2004 11:09:53 +0000 Subject: [PATCH] bitkeeper revision 1.1159.68.3 (41385101Grb5mmJcQ0YiLdCY2dOnCg) Notify device controllers when devices are added or removed so that they can probe for the devices. --- .../drivers/xen/blkfront/blkfront.c | 6 ++ .../drivers/xen/netfront/netfront.c | 6 ++ tools/python/xen/xend/XendClient.py | 2 +- tools/python/xen/xend/XendDomainInfo.py | 25 ++++++-- tools/python/xen/xend/server/blkif.py | 57 +++++++++++++------ tools/python/xen/xend/server/messages.py | 2 + tools/python/xen/xend/server/netif.py | 25 ++++++-- tools/python/xen/xm/main.py | 22 ++++--- .../hypervisor-ifs/io/domain_controller.h | 2 + 9 files changed, 111 insertions(+), 36 deletions(-) diff --git a/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c index 930e469103..259275ebd1 100644 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -1148,6 +1148,12 @@ static void blkif_status_change(blkif_fe_interface_status_changed_t *status) break; + case BLKIF_INTERFACE_STATUS_CHANGED: + /* The domain controller is notifying us that a device has been + * added or removed. + */ + break; + default: printk(KERN_WARNING "Status change to unknown value %d\n", status->status); diff --git a/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c index 85e29d4d25..44aa8e9dde 100644 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c @@ -771,6 +771,12 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status) vif_wake(dev); break; + case NETIF_INTERFACE_STATUS_CHANGED: + /* The domain controller is notifying us that a device has been + * added or removed. + */ + break; + default: printk(KERN_WARNING "Status change to unknown value %d\n", status->status); diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 5041e06cb7..01d6d3df3c 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -548,7 +548,7 @@ class Xend: return self.xendPost(self.domainurl(id), {'op' : 'device_destroy', 'type' : type, - 'index' : idx }) + 'idx' : idx }) def xend_consoles(self): return self.xendGet(self.consoleurl()) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index b86167143b..f582a51145 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -576,6 +576,16 @@ class XendDomainInfo: dl.append(dev) self.devices[type] = dl + def remove_device(self, type, dev): + """Remove a device from a virtual machine. + + @param type: device type + @param dev: device + """ + dl = self.devices.get(type, []) + if dev in dl: + dl.remove(dev) + def get_devices(self, type): """Get a list of the devices of a given type. @@ -812,7 +822,7 @@ class XendDomainInfo: devs = self.get_devices(dev_name) dev_index = len(devs) self.config.append(['device', dev_config]) - d = dev_handler(self, dev_config, dev_index) + d = dev_handler(self, dev_config, dev_index, change=1) return d def device_destroy(self, type, idx): @@ -829,7 +839,8 @@ class XendDomainInfo: dev_config = self.config_device(type, index) if dev_config: self.config.remove(['device', dev_config]) - dev.destroy() + dev.destroy(change=1) + self.remove_device(type, dev) def configure_memory(self): """Configure vm memory limit. @@ -1053,7 +1064,7 @@ def vm_image_netbsd(vm, image): return vm -def vm_dev_vif(vm, val, index): +def vm_dev_vif(vm, val, index, change=0): """Create a virtual network interface (vif). @param vm: virtual machine @@ -1069,11 +1080,13 @@ def vm_dev_vif(vm, val, index): def cbok(dev): dev.vifctl('up', vmname=vm.name) vm.add_device('vif', dev) + if change: + dev.interfaceChanged() return dev defer.addCallback(cbok) return defer -def vm_dev_vbd(vm, val, index): +def vm_dev_vbd(vm, val, index, change=0): """Create a virtual block device (vbd). @param vm: virtual machine @@ -1094,6 +1107,8 @@ def vm_dev_vbd(vm, val, index): vbd.dev = dev vbd.uname = uname vm.add_device('vbd', vbd) + if change: + vbd.interfaceChanged() return vbd defer.addCallback(fn) return defer @@ -1110,7 +1125,7 @@ def parse_pci(val): v = val return v -def vm_dev_pci(vm, val, index): +def vm_dev_pci(vm, val, index, change=0): """Add a pci device. @param vm: virtual machine diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index c3c3eb2de3..60708e24a9 100755 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -3,7 +3,6 @@ """ from twisted.internet import defer -#defer.Deferred.debug = 1 from xen.xend import sxp from xen.xend.XendLogging import log @@ -88,14 +87,12 @@ class BlkifBackendInterface(controller.BackendInterface): self.send_be_disconnect(response=d) def send_be_disconnect(self, response=None): - log.debug('>BlkifBackendController>send_be_disconnect> %s', str(self)) msg = packMsg('blkif_be_disconnect_t', { 'domid' : self.controller.dom, 'blkif_handle' : self.handle }) self.writeRequest(msg, response=response) def send_be_destroy(self, response=None): - log.debug('>BlkifBackendController>send_be_destroy> %s', str(self)) msg = packMsg('blkif_be_destroy_t', { 'domid' : self.controller.dom, 'blkif_handle' : self.handle }) @@ -127,9 +124,28 @@ class BlkifBackendInterface(controller.BackendInterface): msg = packMsg('blkif_fe_interface_status_changed_t', { 'handle' : self.handle, 'status' : BLKIF_INTERFACE_STATUS_CONNECTED, - 'domid' : 0, ## FIXME: should be domid of backend + 'domid' : self.dom, 'evtchn' : self.evtchn['port2'] }) self.controller.writeRequest(msg, response=response) + + def interfaceDisconnected(self): + msg = packMsg('blkif_fe_interface_status_changed_t', + { 'handle' : self.handle, + 'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED, + 'domid' : self.dom, + 'evtchn' : 0 }) + self.controller.writeRequest(msg) + + def interfaceChanged(self): + """Notify the front-end that devices have been added or removed. + The front-end should then probe for devices. + """ + msg = packMsg('blkif_fe_interface_status_changed_t', + { 'handle' : self.handle, + 'status' : BLKIF_INTERFACE_STATUS_CHANGED, + 'domid' : self.dom, + 'evtchn' : 0 }) + self.controller.writeRequest(msg) class BlkifControllerFactory(controller.SplitControllerFactory): """Factory for creating block device interface controllers. @@ -230,9 +246,21 @@ class BlkDev(controller.SplitDev): val.append(['uname', self.uname]) return val - def destroy(self): + def destroy(self, change=0): + """Destroy the device. If 'change' is true notify the front-end interface. + + @param change: change flag + """ log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev) - self.send_be_vbd_destroy() + d = self.send_be_vbd_destroy() + if change: + d.addCallback(lambda val: self.interfaceChanged()) + + def interfaceChanged(self): + """Tell the back-end to notify the front-end that a device has been + added or removed. + """ + self.getBackendInterface().interfaceChanged() def attach(self): """Attach the device to its controller. @@ -295,16 +323,16 @@ class BlkDev(controller.SplitDev): % (self.vdev, status)) return self - def send_be_vbd_destroy(self, response=None): - log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d', - self.controller.dom, self.vdev) + def send_be_vbd_destroy(self): + d = defer.Deferred() backend = self.getBackendInterface() msg = packMsg('blkif_be_vbd_destroy_t', { 'domid' : self.controller.dom, 'blkif_handle' : backend.handle, 'vdevice' : self.vdev }) self.controller.delDevice(self.vdev) - backend.writeRequest(msg, response=response) + backend.writeRequest(msg, response=d) + return d class BlkifController(controller.SplitController): @@ -399,13 +427,8 @@ class BlkifController(controller.SplitController): def recv_fe_driver_status_changed(self, msg, req): val = unpackMsg('blkif_fe_driver_status_changed_t', msg) - # For each backend? - msg = packMsg('blkif_fe_interface_status_changed_t', - { 'handle' : 0, - 'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED, - 'domid' : 0, ## FIXME: should be domid of backend - 'evtchn' : 0 }) - self.writeRequest(msg) + for backend in self.getBackendInterfaces(): + backend.interfaceDisconnected() def recv_fe_interface_connect(self, msg, req): val = unpackMsg('blkif_fe_interface_connect_t', msg) diff --git a/tools/python/xen/xend/server/messages.py b/tools/python/xen/xend/server/messages.py index 8d68d95887..fb94214a64 100644 --- a/tools/python/xen/xend/server/messages.py +++ b/tools/python/xen/xend/server/messages.py @@ -50,6 +50,7 @@ BLKIF_DRIVER_STATUS_UP = 1 BLKIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */ BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */ BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */ +BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */ BLKIF_BE_STATUS_OKAY = 0 BLKIF_BE_STATUS_ERROR = 1 @@ -117,6 +118,7 @@ CMSG_NETIF_BE_DRIVER_STATUS_CHANGED = 32 NETIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */ NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */ NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */ +NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */ NETIF_DRIVER_STATUS_DOWN = 0 NETIF_DRIVER_STATUS_UP = 1 diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 3b4dc25339..3c07333a84 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -5,7 +5,6 @@ import random from twisted.internet import defer -#defer.Deferred.debug = 1 from xen.xend import sxp from xen.xend import Vifctl @@ -208,13 +207,17 @@ class NetDev(controller.SplitDev): val = unpackMsg('netif_be_create_t', msg) return self - def destroy(self): + def destroy(self, change=0): """Destroy the device's resources and disconnect from the back-end - device controller. + device controller. If 'change' is true notify the front-end interface. + + @param change: change flag """ def cb_destroy(val): self.send_be_destroy() self.getBackendInterface().close() + if change: + self.interfaceChanged() log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif) self.vifctl('down') d = self.send_be_disconnect() @@ -256,7 +259,7 @@ class NetDev(controller.SplitDev): { 'handle' : self.vif, 'status' : NETIF_INTERFACE_STATUS_CONNECTED, 'evtchn' : self.evtchn['port2'], - 'domid' : 0, ## FIXME: should be domid of backend + 'domid' : self.backendDomain, 'mac' : self.mac }) self.controller.writeRequest(msg) @@ -265,7 +268,19 @@ class NetDev(controller.SplitDev): { 'handle' : self.vif, 'status' : NETIF_INTERFACE_STATUS_DISCONNECTED, 'evtchn' : 0, - 'domid' : 0, ## FIXME: should be domid of backend + 'domid' : self.backendDomain, + 'mac' : self.mac }) + self.controller.writeRequest(msg) + + def interfaceChanged(self): + """Notify the font-end that a device has been added or removed. + The front-end should then probe the devices. + """ + msg = packMsg('netif_fe_interface_status_changed_t', + { 'handle' : self.vif, + 'status' : NETIF_INTERFACE_STATUS_CHANGED, + 'evtchn' : 0, + 'domid' : self.backendDomain, 'mac' : self.mac }) self.controller.writeRequest(msg) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 2d77bd5ca6..d8c70e75fe 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -737,22 +737,26 @@ class ProgVbdCreate(Prog): info = """Create a new virtual block device for a domain""" def help(self, args): - print args[0], "DOM UNAME DEV MODE" + print args[0], "DOM UNAME DEV MODE [BACKEND]" print """ Create a virtual block device for a domain. - UNAME - device to export, e.g. phys:hda2 - DEV - device name in the domain, e.g. xda1 - MODE - access mode: r for read, w for read-write + UNAME - device to export, e.g. phy:hda2 + DEV - device name in the domain, e.g. xda1 + MODE - access mode: r for read, w for read-write + BACKEND - backend driver domain """ def main(self, args): - if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0]) + n = len(args) + if n < 5 or n > 6: self.err("%s: Invalid argument(s)" % args[0]) dom = args[1] vbd = ['vbd', ['uname', args[2]], ['dev', args[3]], ['mode', args[4]]] + if n == 6: + vbd.append(['backend', args[5]]) server.xend_domain_device_create(dom, vbd) xm.prog(ProgVbdCreate) @@ -766,13 +770,15 @@ class ProgVbdDestroy(Prog): print args[0], "DOM DEV" print """ Destroy vbd DEV attached to domain DOM. Detaches the device -from the domain, but does not destroy the device contents.""" +from the domain, but does not destroy the device contents. +The device indentifier DEV is the idx field in the device +information. This is visible in 'xm vbd-list'.""" def main(self, args): - if len(args!=3): self.err("%s: Invalid argument(s)" % args[0]) + if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0]) dom = args[1] dev = args[2] - sever.xend_domain_device_destroy(dom, "vbd", dev) + server.xend_domain_device_destroy(dom, "vbd", dev) xm.prog(ProgVbdDestroy) diff --git a/xen/include/hypervisor-ifs/io/domain_controller.h b/xen/include/hypervisor-ifs/io/domain_controller.h index 45090aca0f..5de3c2d673 100644 --- a/xen/include/hypervisor-ifs/io/domain_controller.h +++ b/xen/include/hypervisor-ifs/io/domain_controller.h @@ -93,6 +93,7 @@ typedef struct { #define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */ #define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */ #define BLKIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */ +#define BLKIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */ typedef struct { u32 handle; /* 0 */ u32 status; /* 4 */ @@ -357,6 +358,7 @@ typedef struct { #define NETIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */ #define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */ #define NETIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */ +#define NETIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */ typedef struct { u32 handle; /* 0 */ u32 status; /* 4 */ -- 2.30.2